#!/usr/bin/env python
# -*- coding:utf-8 -*-
import os,sys,time
import logging
import multiprocessing
import redis
import yaml
import shutil
import tempfile
import hashlib
import subprocess
from daemon import Daemon

class MyDaemon(Daemon):
    def run(self):
        config_file = open(os.path.dirname(os.path.abspath(__file__)) + '/config.yaml')
        config = yaml.safe_load(config_file)
        config_file.close()
        
        name = 'msg_process'
        logging.basicConfig(format='%(asctime)s - %(levelname)s - %(message)s', filename='/var/log/%s.log' % (name),level=logging.INFO)
        logging.info('%s Started', name)  
        logging.info('Main Process Pid %d', os.getpid())
        
        process = []
        cpu_count = multiprocessing.cpu_count()
        logging.info('the cpu count is %d', cpu_count)    
        
        need_restart = True
        running_sha1sum = None
        try:
            while True:
                if os.path.exists(sys.path[0]+"/worker.py"):
                    sha1sum = self.get_sha1sum(sys.path[0]+"/worker.py") 
                    need_import = False
                    if not running_sha1sum:
                        print '初始化程序'
                        need_import = True
                    else:
                        if running_sha1sum!=sha1sum:
                            print '文件有变动，进行检查'
                            need_import = True
                            
                    if need_import:
                        try:
                            if 'worker' in sys.modules:  
                                del(sys.modules["worker"])
                            import worker
                            running_sha1sum = sha1sum
                        except ImportError:
                            print '文件worker.py有错误'
                            time.sleep(10)
                            continue

                    redis_client = redis.StrictRedis(host=config['redis']['host'], port=config['redis']['port'],db=5)
                    local_publish_time = worker.Version.publish_time
                    remote_publish_time = redis_client.hget('YISA_MSG_WORKER','publish_time')

                    need_update = False
                    need_commit = False
                    if not remote_publish_time:#redis没有缓存程序
                        print '需要提交本机版本到服务器'
                        need_commit = True
                    else:
                        t1 = time.strptime(local_publish_time, "%Y-%m-%d %H:%M:%S")
                        t2 = time.strptime(remote_publish_time, "%Y-%m-%d %H:%M:%S")
                        if t1 > t2:
                            print '需要提交新版本到服务器'
                            need_commit = True
                        elif t1==t2:
                            pass
                        else:
                            print '需要下载新版本到本机'
                            need_update = True
                            
                    if need_commit:
                        file_obj=open(sys.path[0]+"/worker.py") 
                        file_data = file_obj.read()
                        file_obj.close()                  
                        hmdata = {'publish_time':local_publish_time,'file_data':file_data,'sha1sum':sha1sum}
                        redis_client.hmset('YISA_MSG_WORKER', hmdata) 
                        
                    if need_update:     
                        file_data = redis_client.hget('YISA_MSG_WORKER', 'file_data')
                        tmpdir = tempfile.mkdtemp()
                        file_obj=open(tmpdir+"/worker.py", "wb")
                        file_obj.write(file_data)
                        file_obj.flush()
                        file_obj.close()

                        if os.path.exists(tmpdir+"/worker.py"):
                            file_obj=open(tmpdir+"/worker.py") 
                            file_data = file_obj.read()
                            file_obj.close()   
                            xhash = hashlib.sha1()
                            xhash.update(file_data)
                            tmp_sha1sum = xhash.hexdigest()
                            remote_sha1sum = redis_client.hget('YISA_MSG_WORKER', 'sha1sum')
                            if tmp_sha1sum==remote_sha1sum:
                                shutil.copy(tmpdir+"/worker.py",sys.path[0]+"/worker.py")
                                if 'worker' in sys.modules:  
                                    del(sys.modules["worker"])
                                    need_restart = True
                            else:
                                print '文件校验不匹配,更新失败'
                        else:
                            print '没有找到临时文件worker.py'
                        shutil.rmtree(tmpdir, ignore_errors=True)
                        
                    if 'worker' not in sys.modules:  
                        try:
                            import worker
                            running_sha1sum = self.get_sha1sum(sys.path[0]+"/worker.py") 
                        except ImportError:
                            print '文件worker.py有错误'
                            time.sleep(10)
                            continue
                    if need_restart:
                        print '重启程序'
                        for p in process:    
                            p.terminate()
                        process = []
                        for x in xrange(0, cpu_count):
                            process.append(worker.Dispatcher(config,cpu_count))
                        for p in process:
                            p.start()
                        need_restart = False
                else:
                    print '没有找到worker.py文件'
                time.sleep(5)
        except KeyboardInterrupt:
            for p in process:
                p.terminate()
            process = []
            sys.exit(1)
        except Exception, e:
            print str(e)
            sys.exit(1)   
    
    def get_sha1sum(self,file_path):
        file_obj=open(file_path) 
        file_data = file_obj.read()
        file_obj.close()   
        xhash = hashlib.sha1()
        xhash.update(file_data)
        sha1sum = xhash.hexdigest()
        return sha1sum    
    
if __name__ == "__main__":
    daemon = MyDaemon('/var/run/run_me.pid')
    if len(sys.argv) == 2:
        if 'start' == sys.argv[1]:
            daemon.start()
        elif 'stop' == sys.argv[1]:
            daemon.stop()
        elif 'restart' == sys.argv[1]:
            daemon.restart()
        else:
            print "Unknown command"
            sys.exit(2)
        sys.exit(0)
    else:
        print "usage: %s start|stop|restart" % sys.argv[0]
        sys.exit(2)
